//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.tuiofx.internal.base;

import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.tuiofx.Configuration;
import org.tuiofx.internal.util.LogUtils;
import org.tuiofx.internal.util.Util;

public class CoordinatesMapping {
    private final Configuration config;
    private Scene scene;
    private final Stage stage;
    private double screenWidth;
    private double screenHeight;
    private GraphicsDevice graphicDevice;

    public CoordinatesMapping(Stage stage, Configuration config) {
        this.stage = stage;
        this.scene = stage.getScene();
        this.config = config;
        GraphicsDevice[] _screenDevices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
        this.graphicDevice = _screenDevices[config.getScreenDevice()];
        if (this.scene != null) {
            this.addSceneDimensionListeners();
            this.updateScreenWidthHeight();
        }

        stage.sceneProperty().addListener((observable, oldScene, newScene) -> {
            this.scene = newScene;
            this.addSceneDimensionListeners();
        });
    }

    private void addSceneDimensionListeners() {
        this.scene.widthProperty().addListener((observable, oldValue, newValue) -> {
            this.updateScreenWidth();
        });
        this.scene.heightProperty().addListener((observable, oldValue, newValue) -> {
            this.updateScreenHeight();
        });
    }

    private void updateScreenWidthHeight() {
        this.updateScreenWidth();
        this.updateScreenHeight();
    }

    private void updateScreenWidth() {
        checkState(this.scene != null);
        if (this.config.isUseIndirectInputDevice()) {
            this.screenWidth = this.scene.getWidth();
        } else {
            this.screenWidth = (double)this.graphicDevice.getDisplayMode().getWidth();
        }
        LogUtils.debug("Screen width= "+this.screenWidth);
    }

    private void updateScreenHeight() {
        checkState(this.scene != null);
        this.screenHeight = (double)this.graphicDevice.getDisplayMode().getHeight();
        if (this.config.isUseIndirectInputDevice()) {
            this.screenHeight = this.scene.getHeight();
        } else {
            this.screenHeight = (double)this.graphicDevice.getDisplayMode().getHeight();
        }

        LogUtils.debug("Screen height= "+this.screenHeight);
    }

    public Point2D computeTuioTouchToSceneCoordinates(double x, double y) {
        Point2D coords = new Point2D(this.computeTouchSceneCoordinateX(x), this.computeTouchSceneCoordinateY(y));
        return coords;
    }

    public Point2D computeTuioTouchToScreenCoordinates(double x, double y) {
        Point2D coords = new Point2D(this.computeTouchScreenCoordinateX(x), this.computeTouchScreenCoordinateY(y));
        return coords;
    }

    private double computeTouchSceneCoordinateX(double x) {
        checkState(this.scene != null);
        if (this.config.isUseIndirectInputDevice()) {
            return this.computeTouchScreenCoordinateX(x);
        } else {
            double cursorSceneX = this.computeTouchScreenCoordinateX(x) - Util.getOffsetX(this.scene);
            return cursorSceneX;
        }
    }

    private double computeTouchSceneCoordinateY(double y) {
        checkState(this.scene != null);
        if (this.config.isUseIndirectInputDevice()) {
            return this.computeTouchScreenCoordinateY(y);
        } else {
            double cursorSceneY = this.computeTouchScreenCoordinateY(y) - Util.getOffsetY(this.scene);
            return cursorSceneY;
        }
    }

    private double computeTouchScreenCoordinateX(double x) {
        return x * this.screenWidth;
    }

    private double computeTouchScreenCoordinateY(double y) {
        return y * this.screenHeight;
    }

    private static void checkState(boolean expression) {
        if (!expression) {
            throw new IllegalStateException("Scene is null.");
        }
    }

    public FXCoordinates translateFXCoordinatesToScene(double screenX, double screenY, Scene targetScene) {
        Point2D sceneXY = this.translateSceneCoordinatesToAnotherScene(screenX, screenY, targetScene);
        Point2D screenXY;
        if (this.config.isUseIndirectInputDevice()) {
            screenXY = new Point2D(screenX + Util.getOffsetX(this.scene), screenY + Util.getOffsetY(this.scene));
        } else {
            screenXY = new Point2D(screenX, screenY);
        }

        return new FXCoordinates(screenXY, sceneXY);
    }

    private Point2D translateSceneCoordinatesToAnotherScene(double screenX, double screenY, Scene targetScene) {
        double targetSceneX = targetScene.getWindow().getX() + targetScene.getX();
        double targetSceneY = targetScene.getWindow().getY() + targetScene.getY();
        if (this.config.isUseIndirectInputDevice()) {
            targetSceneX -= Util.getOffsetX(this.scene);
            targetSceneY -= Util.getOffsetY(this.scene);
        }

        double sceneX = screenX - targetSceneX;
        double sceneY = screenY - targetSceneY;
        return new Point2D(sceneX, sceneY);
    }
}
